#include "ZipNode.h"
#include "stdlib.h"

ZipNode::ZipNode(const char* name)
{
    branches_ = 0;
    this->root_ = 0;
    this->root_ = new char[strlen(name) + 1];
    strcpy(this->root_, name);
}

ZipNode::ZipNode()
{
    branches_ = 0;
    this->root_ = 0;
}

ZipNode::ZipNode(const ZipNode& other)
{
    this->branches_ = other.branches_;
    this->root_ = other.root_;
    this->branchCounter_ = other.branchCounter_;
    this->currentBranches_ = other.currentBranches_;
}

ZipNode::~ZipNode()
{
    if (this->root_)
	delete this->root_;
}

void ZipNode::addNode(ZipNode* node)
{

    if (containsInNode(node->root_) == false)
    {
	INFO("Add<<%s>>", node->getRoot());
	if (this->branchCounter_ > currentBranches_)
	    resizeBranches();
	this->branches_[this->branchCounter_] = *node;
	this->branchCounter_++;
    }
}

void ZipNode::operator=(const ZipNode& orig)
{
    this->branches_ = orig.branches_;
    this->root_ = orig.root_;
    this->branchCounter_ = orig.branchCounter_;
    this->currentBranches_ = orig.currentBranches_;
}

bool ZipNode::contains(const char* orig)const
{
    if (strcmp(orig, this->root_) == 0)
    {
	return true;
    }
    else if (this->branchCounter_ > 0)
	for (int i = 0; i<this->branchCounter_; i++)
	{
	    if (this->branches_[i].contains(orig))
		return true;
	}
    return false;
}

ZipNode* ZipNode::browse(const char* name)
{
    ZipNode* found = 0;
    if (contains(name))
    {
	if (strcmp(name, this->root_) == 0)
	{
	    found = this;
	}
	else if (this->branchCounter_ > 0)
	    for (int i = 0; i<this->branchCounter_; i++)
	    {
		found = this->branches_[i].browse(name);
		if (found)
		    break;
	    }
    }

    return found;

}

void ZipNode::traverse(PF_Traverse traverseFunction)
{
    traverseFunction();
}

bool ZipNode::containsInNode(const char* orig) const
{
    for (int i = 0; i<this->branchCounter_; i++)
    {
	if (strcmp(orig, this->branches_[i].root_) == 0)
	{
	    return true;
	}
    }
    return false;
}

void ZipNode::remove(const char* element)
{
    ZipNode* nodeToRemove = browse(element);
    if (nodeToRemove)
	nodeToRemove = NULL;
}

ZipNode* ZipNode::getBranches()const
{
    return this->branches_;
}

char* ZipNode::getRoot()const
{
    return this->root_;
}

void ZipNode::setRoot(const char* rootToPlc)
{
    if (this->root_)
	delete this->root_;
    this->root_ = 0;
    this->root_ = new char[strlen(rootToPlc) + 1];
    strcpy(this->root_, rootToPlc);
}

int ZipNode::size() const
{
    return this->branchCounter_;
}

void ZipNode::resizeBranches()
{
    ZipNode* tmp = (ZipNode*) realloc(this->branches_, sizeof (ZipNode)*(this->branchCounter_ + DEFAULT_SIZE));
    this->branches_ = tmp;
    this->currentBranches_ += DEFAULT_SIZE;
}
